<?php
/**
 * My_Model
 *
 * @package My
 * @author charles
 * @copyright 2009
 * @version $Id$
 * @access public
 */
class My_Model extends Zend_Db_Table_Abstract
{
    protected $_name;
    public $_debug = false;
    protected $db = false;
    public $pageNumber = 1;
    public $perPage = 10;
    public $sh_language = null;
    /**
     * My_Model::__construct()
     *
     * @return
     */
    function __construct ($db = null)
    {
//        if (! $db instanceof Zend_Db_Table_Abstract) {
//            $db = Zend_Db_Table_Abstract::getDefaultAdapter();
//        }
//        $db = new Zend_Auth_Adapter_DbTable($db);
//        parent::__construct($db);
//        $this->db = $db;
    }
    /**
     * My_Model::save()
     *
     * @param mixed $data
     * @return
     */
    public function save ($data)
    {
        $info = $this->info();
        $data = $this->sanitize($data);
        if (! empty($data[$info['primary'][1]])) {
            $primary_key = $info['primary'][1];
            $primary_value = $data[$info['primary'][1]];
            unset($data[$info['primary'][1]]);
            $result = $this->update($data, "{$primary_key} = {$primary_value}");
            $data[$primary_key] = $primary_value;
        } else {
            unset($data[$info['primary'][1]]);
            $result = $this->insert($data);
            $data[$info['primary'][1]] = $result;
        }
        if (! empty($this->zh_language))
            $this->saveTranslation($data);
        return $result;
    }
    /**
     * My_Model::togglePublish()
     *
     * @param mixed $id
     * @return
     */
    public function togglePublish ($id)
    {
        $menu = $this->fetchRow("id={$id}");
        if ($menu->published == 1)
            $publish = 0;
        else
            $publish = 1;
        if ($this->update(array('published' => $publish), 'id = ' . $id))
            return $publish;
        else
            return $menu->published;
    }
    /**
     * My_Model::read()
     *
     * @param mixed $id
     * @param mixed $where
     * @return
     */
    public function read ($id, $where = array())
    {
        if (empty($id)) {
            $info = $this->info();
            $object = (object) array();
            foreach ($info['cols'] as $col)
                $object->$col = $info['metadata'][$col]['DEFAULT'];
            return $object;
        }
        $cond = array("id = {$id}");
        foreach ($where as $c)
            $cond[] = $c;
        return $this->fetchRow($cond);
    }
    /**
     * My_Model::delete()
     *
     * @param mixed $id
     * @return
     */
    public function delete ($id)
    {
        return parent::delete('id = ' . $id);
    }
    /**
     * My_Model::deleteAll()
     *
     * @param mixed $id
     * @return
     */
    public function deleteAll ($where)
    {
        return parent::delete($where);
    }
    /**
     * My_Model::ordering()
     *
     * @param mixed $data
     * @return
     */
    public function ordering ($data)
    {
        foreach ($data as $id => $position) {
            $row = array('id' => $id , 'ordering' => $position);
            $this->save($row);
        }
    }
    /**
     * My_Model::findAll()
     *
     * @param mixed $where
     * @param mixed $order
     * @param mixed $count
     * @param mixed $offset
     * @return
     */
    public function findAll ($where = null, $order = null, $count = null, $offset = null, $pagination = false)
    {
        $select = new Zend_Db_Table_Select($this);
        if (! is_null($where))
            $select->where($where);
        if (! is_null($order)) {
            $select->order($order);
        }
        if (! is_null($count) || ! is_null($offset)) {
            $select->limit($count, $offset);
        }
        if ($pagination) {
            $paginator = Zend_Paginator::factory($select);
            $paginator->setCurrentPageNumber($this->pageNumber);
            $paginator->setItemCountPerPage($this->perPage);
            $results = $paginator;
        } else {
            $results = $this->fetchAll($select, $order, $count, $offset);
        }
        if (! empty($this->_traslateField))
            foreach ($results as $result)
                $result = $this->translateData($result);
        if (! empty($this->_referenceMaps)) {
            foreach ($this->_referenceMaps as $name => $ref) {
                foreach ($results as $result) {
                    $result = $this->translateData($result);
                    if (isset($result->$name)) {
                        if (! class_exists($ref['refModel']))
                            throw new My_Exception("Model {$ref['refModel']} not found");
                        $model = new $ref['refModel']();
                        $value = (string) $result->$name;
                        if (! empty($value)) {
                            $new_value = $model->findRow(array("{$ref['refColumn']} = $value"));
                            if (empty($new_value)) {
                                $temp = (object) array();
                                $cols = $model->info();
                                if (! empty($cols)) {
                                    foreach ($cols['cols'] as $col)
                                        $temp->$col = '';
                                    $new_value = $temp;
                                }
                            }
                            $result->$name = $new_value;
                        } else {
                            $temp = (object) array();
                            $cols = $model->info();
                            if (! empty($cols)) {
                                foreach ($cols['cols'] as $col)
                                    $temp->$col = '';
                                $result->$name = $temp;
                            }
                        }
                    }
                }
            }
        }
        return $results;
    }
    /**
     * My_Model::findRow()
     *
     * @param mixed $where
     * @param mixed $order
     * @return
     */
    public function findRow ($where = null, $order = null)
    {
        if (is_numeric($where))
            $where = "id = {$where}";
        if (! is_null($where))
            $result = parent::fetchRow($where, $order);
        else
            $result = parent::fetchNew();
        $result = $this->translateData($result);
        if (! empty($this->_referenceMaps)) {
            foreach ($this->_referenceMaps as $name => $ref) {
                if (isset($result->$name)) {
                    if (! class_exists($ref['refModel']))
                        throw new My_Exception("Model {$ref['refModel']} not found");
                    $model = new $ref['refModel']();
                    $value = (string) $result->$name;
                    if (! empty($value)) {
                        if ($ref['refModel'] == get_class($this))
                            $new_value = $model->fetchRow(array("{$ref['refColumn']} = $value"));
                        else
                            $new_value = $model->findRow(array("{$ref['refColumn']} = $value"));
                        if (empty($new_value)) {
                            $temp = (object) array();
                            $cols = $model->info();
                            if (! empty($cols)) {
                                foreach ($cols['cols'] as $col)
                                    $temp->$col = '';
                                $new_value = $temp;
                            }
                        }
                        $result->$name = $new_value;
                    } else {
                        $temp = (object) array();
                        $cols = $model->info();
                        if (! empty($cols)) {
                            foreach ($cols['cols'] as $col)
                                $temp->$col = '';
                            $result->$name = $temp;
                        }
                    }
                }
            }
        }
        return $result;
    }
    /**
     * My_Model::translateData()
     *
     * @param mixed $result
     * @return
     */
    public function translateData ($result)
    {
        $TranslationModel = new Language_Model_Translation();
        $select = new Zend_Db_Table_Select($TranslationModel);
        if (! empty($result) && ! empty($this->_traslateField)) {
            $keys = array_keys($result->toArray());
            $class_name = get_class($this);
            $this->zh_language = Zend_Registry::get('zh_language');
            foreach ($keys as $key)
                $select->orWhere(" fieldid = '{$result->id}' AND field='{$key}' AND lang = '{$this->zh_language->id}' AND model = '{$class_name}' ");
            $translations = parent::fetchAll($select);
            if (! empty($translations))
                foreach ($translations as $translation) {
                    $field = $translation->field;
                    $result->$field = $translation->value;
                }
        }
        return $result;
    }
    public function saveTranslation ($data)
    {
        if (! empty($this->_traslateField)) {
            $info = $this->info();
            $model_name = get_class($this);
            $field_id = $info['primary'][1];
            $fields = $this->_traslateField;
            $TranslationModel = new Language_Model_Translation();
            foreach ($fields as $field) {
                $select = new Zend_Db_Table_Select($TranslationModel);
                $select->where("model = '{$model_name}'");
                $select->where("fieldid = '{$data[$field_id]}'");
                $select->where("field = '{$field}'");
                $select->where("lang = '{$this->zh_language->id}'");
                $trsl_row = $TranslationModel->fetchRow($select);
                if (isset($data[$field])) {
                    if (! empty($trsl_row)) {
                        $trsl_row->value = $data[$field];
                        $TranslationModel->update($trsl_row->toArray(), "id = '{$trsl_row->id}'");
                    } else {
                        $temp = array();
                        $temp['model'] = $model_name;
                        $temp['field'] = $field;
                        $temp['fieldid'] = $data[$field_id];
                        $temp['value'] = $data[$field];
                        $temp['lang'] = $this->zh_language->id;
                        $TranslationModel->insert($temp);
                    }
                }
            }
        }
    }
    public function sanitize ($data)
    {
        $info = $this->info();
        //debug($info);
        foreach ($data as $key => $item) {
            if (! in_array($key, $info['cols']) or is_array($item) or is_array($item))
                unset($data[$key]);
            else {
                if ($info['metadata'][$key]['DATA_TYPE'] == 'int')
                    $data[$key] = (int) $data[$key];
            }
        }
        return $data;
    }
    public function getEmpty ()
    {
        $temp = (object) array();
        $cols = $this->info();
        if (! empty($cols)) {
            foreach ($cols['cols'] as $col)
                $temp->$col = '';
        }
        return $temp;
    }
    public function getTree ($field = 'parent', $where = null, $parent = 0)
    {
        $select = new Zend_Db_Table_Select($this);
        $select->where("({$field} = $parent) OR ({$field} IS NULL)");
        $select->where($where);
        $temp = $this->fetchAll($select);
        if (! empty($temp)) {
            foreach ($temp as $t)
                $t = $this->translateData($t);
        }
        $items = $temp->toArray();
        foreach ($items as $key => $item) {
            $childs = $this->getTree($field, $where, $item['id']);
            $items[$key]['childs'] = (object) $childs;
        }
        return (object) $items;
    }
}